package main.view;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import main.KeysExecution;
import main.KeysVal;
import main.constraint.XDF;

//import update.Update_xml;

/**
 * Initial (GUI)
 * -------------------------------------
 * 
 * - This class represents the vision of the program.
 * - Its extend of JFrame and use Swing 
 * 
 * @author ooooo
 * @version 
 */


public class Initial extends JFrame
{
	private static final long serialVersionUID = 1L;
	private JTextArea t1, t2, t3;
	private JPanel t1p, t2p;
	private JButton openF, keysF, kTree, updtF, incvF;
	private BorderLayout layout;
	private String filename = new String();
	private String fileUpd = new String();
	private KeysExecution ke = new KeysExecution();
	private KeysVal kv = new KeysVal();
	private JOptionPane jp = new JOptionPane(); // for indicade the size of file ultrapasse the textarea
	public static String ErrorMessage = new String("");
	public static FileWriter fw;
	File f = null;
	JFileChooser fileChooser = new JFileChooser();
	
	public Initial()
	{
		super("XDF Validation");
		
		Container c = getContentPane();
        
		layout = new BorderLayout(5,5);
		c.setLayout(layout);

		t1 = new JTextArea(10, 15);
		t1.setEditable(false);
		t2 = new JTextArea(10, 15);
		t2.setEditable(false);
		
        
		t1p = new JPanel();
		t1p.setBorder(BorderFactory.createTitledBorder("XML Document / Constraints"));  
		t1p.setLayout(new GridLayout(1,2));
		t1p.add(new JScrollPane(t1));
		t1p.add(new JScrollPane(t2));
		c.add(t1p, BorderLayout.CENTER);		
		
		t3 = new JTextArea(10, 15);
		t3.setEditable(false);
				
		t2p = new JPanel();
		t2p.setBorder(BorderFactory.createTitledBorder("Validation Results:"));  
		t2p.setLayout(new GridLayout(1,2));
		t2p.add(new JScrollPane(t3));
		c.add(t2p, BorderLayout.SOUTH);
					
		openF = new JButton("Open XML File");
		openF.setPreferredSize(new Dimension(40,25));
		openF.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				// apenas para testar aquivos grandes
				//filename = "c:\\eclipse\\workspace\\toxgene\\samples\\other\\L1a.xml";
				//t1.setText("Teste com arquivo L1a.xml - Arquivo muito grande para ser aberto");
					//filename = selectFile();
					int size = 70000000;
					filename = selectFile2();
					File f = new File (filename);
					if (f.length() < size) // Tests the file size if it is larger than 50MB will not be displayed
						t1.setText(openFile(filename));
					else
					{
						JOptionPane.showMessageDialog(null, "The file  " + filename + "\n is larger than " + size+" bytes, will not be displayed.");
						t1.setText("The file: \n"+ filename+ "\n" + " is very big to be displayed.");
					}
				keysF.setEnabled(true);
			}
		});
		
		keysF = new JButton("Enter XML-XDF");		
		keysF.setEnabled(false);
		keysF.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{			
				XDF k = new XDF();
				String KName = new String();// = "x1";
				KName = JOptionPane.showInputDialog("Enter XDF Name"); 
				k.setNameConstraint(KName);
				String KFsa1 = JOptionPane.showInputDialog("Enter context Path");
				k.setContextFsa(KFsa1);
				String KFsa2 = JOptionPane.showInputDialog("Enter left Path");
				k.setSourceFsa(KFsa2);
				String typeLeftPath = JOptionPane.showInputDialog("Enter type of equality associated with dependence (v or n whith commas ex. 'v,n,v')");
				k.setEquality(typeLeftPath,"l");
				String KFsa3 = JOptionPane.showInputDialog("Enter right Path");
				k.setTargetFsa(KFsa3);
				String typeRightPath = JOptionPane.showInputDialog("Enter type of equality associated with dependence(v or n)");
				k.setEquality(typeRightPath,"r");
				ke.addKeys(k);			
				
				t2.setText(ke.toString());
				kTree.setEnabled(true);
			}
		});

		kTree = new JButton("Validation");
		kTree.setEnabled(false);
		kTree.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				try
				{										 
					// ---- ??? InputStream is = new ByteArrayInputStream(filename.getBytes("UTF-8"));
					//t3.append(keyValidation(filename,ke));
					keyValidation(filename,ke);
				}
				catch (Exception ex)
				{
					System.out.println(ex.getMessage());
				}
			}
		});

		updtF = new JButton("Update List");		
		updtF.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				t1p.setBorder(BorderFactory.createTitledBorder("XInitial app = ML Document / Update Operations List"));  
				fileUpd = selectFile();
				t2.setText(openFile(fileUpd));
		    }
		});
    	
		incvF = new JButton("Update Validation");
		/*incvF.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
						
				t3.append("\nIncremental Validation Results: \n");
				Update_xml updateObject = new Update_xml();
				try{
				  System.out.println("begin updates");	
				  updateObject.update(fileUpd,filename,kv);
				  t3.append(openFile("result.xml"));
				  String op = new String();
				  for(int i=0;i<Update_xml.NbOperation;i++)
	              {      
		               op += Update_xml.operations[i].getOp()+" "+
		                     Update_xml.operations[i].getPos()+
                             " -> Accepted: "+Update_xml.operations[i].getResult()+"\n";
	              }
				  t3.append(op);
				  
				} catch (Exception ex){};
		    }
		});*/
		
    	Panel t3p = new Panel();
    	Box b = Box.createVerticalBox();

    	openF.setPreferredSize(new Dimension(150,30));
    	openF.setMaximumSize(new Dimension(150,30));  
    	keysF.setPreferredSize(new Dimension(150,30));
    	keysF.setMaximumSize(new Dimension(150,30));  
    	kTree.setPreferredSize(new Dimension(150,30));
    	kTree.setMaximumSize(new Dimension(150,30));  
    	updtF.setPreferredSize(new Dimension(150,30));
    	updtF.setMaximumSize(new Dimension(150,30));  
    	incvF.setPreferredSize(new Dimension(150,30));
    	incvF.setMaximumSize(new Dimension(150,30));  
    	 
		b.add(openF);
		b.add(keysF);
		b.add(kTree);
		b.add(updtF);
		b.add(incvF);
		t3p.add(b);
		c.add(t3p, BorderLayout.WEST);
    	
		
		setSize(800, 400);
		setVisible(true);
	}

	public String keyValidation(String filename, KeysExecution ke)
	{	
		//Executa normalmente 
		t3.setText(kv.parseKeysVal(filename, ke) + "\n" + ErrorMessage);

		//Executa fazendo testes em arquivos pr�-definidos
		//t3.setText(kv.parseKeysValTestes(filename, ke) + "\n" + ErrorMessage);
		
		return (kv.getResult());
	}

	/**
	 * This function its a JFileChoser
	 * @return the file select, its a string
	 */
	private String selectFile()
	{
		String name = new String();
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		
		int result = fileChooser.showOpenDialog(this);
		
		if (result == JFileChooser.CANCEL_OPTION)
			return "error";
		
		File fname = fileChooser.getSelectedFile();
		
		if (fname == null || fname.getName().equals(""))
			JOptionPane.showMessageDialog(this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE);
		else 
		{
			name = "" + fname;		
		}
		
		return name;
	}
	
	
	private String selectFile2()
	{
		
		String name = new String();
		
		fileChooser.setDialogTitle("Select a xml file");
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		filterFile(fileChooser);
		String s = System.getProperty("user.dir");
		File f1 = new File (s);
		fileChooser.setCurrentDirectory(f1);
		
		//Save the last path selected to oppen the chooser in there
		if (f != null )
		{
			String path = fileChooser.getSelectedFile().getAbsolutePath();
			String lastPath = path.substring(0, path.lastIndexOf("\\"));
			f = new File(lastPath);
			fileChooser.setCurrentDirectory(f);
			path = "" + f;
		}
		
		int result = fileChooser.showDialog(fileChooser.getParent(), null) ;

		if (result == JFileChooser.CANCEL_OPTION)
			return "error";
		else
		{
			name = fileChooser.getSelectedFile().getAbsolutePath() ;
			f = new File (name);
			return name;
		}
	}
	
	/**
	 * Lets just xml files are selected by the JFileChooser
	 */
	public void filterFile(JFileChooser j)
	{			
		j.setFileFilter(new javax.swing.filechooser.FileFilter()
		{
			public boolean accept (File f)
			{
				return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
			}
			
			//Text show to user
			public String getDescription()
			{
				return "Only files xml (.xml)";
			}
			
		});
	}		


	
	
	/**
	 * This function read the file xml
	 * @param fname string
	 * @return string of file or error
	 */
	private String openFile(String fname)
	{
		String xml = new String();
		try
		{
			FileInputStream in = new FileInputStream(fname);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String s = br.readLine();
			while (s != null)
			{
				xml = xml + s + "\n";
				s = br.readLine();
			}
			
			return (xml);			
		}
		catch (Exception e)
		{
			System.out.println(e);
			xml = "error: corrupted file";
			return (xml);
		}
	}

	/**
	 * This function call the Initial Frame
	 * @param args
	 * @return void
	 */
	public static void main(String[] args)
	{
		Initial app = new Initial();		
		app.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.out.println("Fim");
				System.exit(0);
			}
		});
	}	
}
